home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / diskmags / amiga_9301b.lha / Schach / Sourcecode / Zug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-15  |  11.6 KB  |  428 lines

  1.  
  2.  /* Zug.c : individuelle Zugbewertung */
  3.  
  4. #include "Adt.h"
  5.  
  6. Feld * Bauer();
  7. Feld * Springer();
  8. Feld * RestFig();
  9. struct Knoten * GibKnoten();
  10.  
  11. long ZugBaumI();
  12. long ZugBaumII();
  13.  
  14. int Figurwert[] = { 0, 100, 300, 300, 500, 900, 21000 };
  15. int Stelwert[][ 8 ][ 8 ] = {
  16.   { /* wbauer: */
  17.   {  0,  0,  0,  0,  0,  0,  0,  0 },
  18.   { 35, 70, 55, 75, 75, 55, 70, 35 },
  19.   { 30, 65, 50, 70, 70, 50, 65, 30 },
  20.   { 25, 60, 45, 65, 65, 45, 60, 25 },
  21.   { 20, 55, 40, 62, 62, 40, 55, 20 },
  22.   { 10, 50, 30, 40, 40, 30, 50, 10 },
  23.   {  0,  0,  0,  0,  0,  0,  0,  0 },
  24.   {  0,  0,  0,  0,  0,  0,  0,  0 } },
  25.   { /* sbauer: */
  26.   {  0,  0,  0,  0,  0,  0,  0,  0 },
  27.   {  0,  0,  0,  0,  0,  0,  0,  0 },
  28.   { 10, 50, 30, 40, 40, 30, 50, 10 },
  29.   { 20, 55, 40, 62, 62, 40, 55, 20 },
  30.   { 25, 60, 45, 65, 65, 45, 60, 25 },
  31.   { 30, 65, 50, 70, 70, 50, 65, 30 },
  32.   { 35, 70, 55, 75, 75, 55, 70, 35 },
  33.   {  0,  0,  0,  0,  0,  0,  0,  0 } },
  34.   { /* springer: */
  35.   {  0, 12, 24, 24, 24, 24, 12,  0 },
  36.   { 12, 24, 48, 48, 48, 48, 24, 12 },
  37.   { 24, 48, 72, 72, 72, 72, 48, 24 },
  38.   { 24, 48, 72, 72, 72, 72, 48, 24 },
  39.   { 24, 48, 72, 72, 72, 72, 48, 24 },
  40.   { 24, 48, 72, 72, 72, 72, 48, 24 },
  41.   { 12, 24, 48, 48, 48, 48, 24, 12 },
  42.   {  0, 12, 24, 24, 24, 24, 12,  0 } },
  43.   { /* laeufer: */
  44.   {  7,  7,  0,  0,  0,  0,  7,  7 },
  45.   {  7, 21, 21, 14, 14, 21, 21,  7 },
  46.   { 21, 21, 35, 35, 35, 35, 21, 21 },
  47.   { 35, 14, 35, 35, 35, 35, 14, 35 },
  48.   { 35, 14, 35, 35, 35, 35, 14, 35 },
  49.   { 21, 21, 35, 35, 35, 35, 21, 21 },
  50.   {  7, 21, 21, 14, 14, 21, 21,  7 },
  51.   {  7,  7,  0,  0,  0,  0,  7,  7 } },
  52.   { /* turm: */
  53.   {  0, 10, 20, 30, 30, 20, 10,  0 },
  54.   { 10, 10, 20, 30, 30, 20, 10, 10 },
  55.   { 20, 20, 20, 25, 25, 20, 20, 20 },
  56.   { 20, 20, 20, 25, 25, 20, 20, 20 },
  57.   { 20, 20, 20, 25, 25, 20, 20, 20 },
  58.   { 20, 20, 20, 25, 25, 20, 20, 20 },
  59.   { 10, 10, 20, 30, 30, 20, 10, 10 },
  60.   {  0, 10, 20, 30, 30, 20, 10,  0 } },
  61.   { /* dame: */
  62.   {  4,  0,  0,  4,  4,  0,  0,  4 },
  63.   {  0, 12,  8, 12, 12,  8, 12,  0 },
  64.   {  0,  8, 20, 20, 20, 20,  8,  0 },
  65.   {  0,  8, 16, 28, 28, 16,  8,  0 },
  66.   {  0,  8, 16, 28, 28, 16,  8,  0 },
  67.   {  0,  8, 20, 20, 20, 20,  8,  0 },
  68.   {  0, 12,  8, 12, 12,  8, 12,  0 },
  69.   {  4,  0,  0,  4,  4,  0,  0,  4 } },
  70.   { /* koenig: */
  71.   {  0, 12, 12, 12, 12, 12, 12,  0 },
  72.   { 12, 30, 30, 30, 30, 30, 30, 12 },
  73.   { 12, 30, 30, 30, 30, 30, 30, 12 },
  74.   { 12, 30, 30, 30, 30, 30, 30, 12 },
  75.   { 12, 30, 30, 30, 30, 30, 30, 12 },
  76.   { 12, 30, 30, 30, 30, 30, 30, 12 },
  77.   { 12, 30, 30, 30, 30, 30, 30, 12 },
  78.   {  0, 12, 12, 12, 12, 12, 12,  0 } } };
  79.  
  80.  
  81. struct Zugstat * BesterZug( s, fa, ite, sp )
  82.     Figur s[ 9 ][ 9 ];
  83.     Farbe fa;
  84.     int ite;
  85.     Special sp;
  86. {
  87.     static struct Zugstat zs;
  88.     struct Knoten *k, *ks;
  89.     struct Zug *z;
  90.     long kn;
  91.     int best, ok, sx, sy, zx, zy;
  92.     Figur fi;
  93.     int spz;
  94.  
  95.     Zeit( 0L );
  96.     kn = ZugBaumI( s, &k, &k, fa, ite, sp );
  97.  
  98.     if( kn ) {
  99.          /* besten Zug aussuchen und merken: */
  100.         best = -30000; ks = k;
  101.         do {
  102.             if( ks->zugwertung > best ) {
  103.  
  104.                 sx = ks->zug.start >> 4;    sy = ks->zug.start & yposmask;
  105.                 zx = ks->zug.ziel >> 4;     zy = ks->zug.ziel & yposmask;
  106.                  /* Zug ausführen: */
  107.         fi = s[zx][zy]; s[sx][sy] = leer; spz = 0;
  108.         if( (ks->zug.figur&figmask)==koenig && (zx-sx==2 ||
  109.           sx-zx==2) ) {
  110.             spz = 1; s[zx][zy] = ks->zug.figur;
  111.             if( zx==7 ) {
  112.             s[6][sy] = s[8][sy]; s[8][sy] = leer;
  113.             } else {
  114.             s[4][sy] = s[1][sy]; s[1][sy] = leer;
  115.             }
  116.         } else if( (ks->zug.figur&figmask)==bauer && fi==leer &&
  117.           sx!=zx ) {
  118.             spz = 1; s[zx][zy] = ks->zug.figur; s[zx][sy] = leer;
  119.         } else if( (ks->zug.figur&figmask)==bauer && (zy==1 ||
  120.           zy==8) ) {
  121.             s[zx][zy] = (ks->zug.figur&farbmask)|dame;
  122.         } else
  123.             s[zx][zy] = ks->zug.figur;
  124.  
  125.                 ok = !IstSchach( s, fa, 0, sp );
  126.  
  127.                  /* Zug zurücknehmen: */
  128.         s[sx][sy] = ks->zug.figur; s[zx][zy] = fi;
  129.         if( spz )
  130.             if( zx-sx==2 || sx-zx==2 ) {
  131.             if( zx==7 ) {
  132.                 s[8][sy] = s[6][sy]; s[6][sy] = leer;
  133.             } else {
  134.                 s[1][sy] = s[4][sy]; s[4][sy] = leer;
  135.             }
  136.             } else
  137.             s[zx][sy] = bauer|(zy==6?schwarz:weiss);
  138.  
  139.         ok &= RochOK( s, ks->zug.start, ks->zug.ziel, sp );
  140.  
  141.                 if( ok ) { /* ins (bei Roch. durchs) Schach ziehen verboten */
  142.                     best = ks->zugwertung;
  143.                     z = &(ks->zug);
  144.                 } else
  145.                     ks->zugwertung = -30000;
  146.             }
  147.             ks = ks->nachbar;
  148.         } while( ks );
  149.     } else
  150.         return( 0L );
  151.  
  152.     zs.zug.figur = z->figur;
  153.     zs.zug.start = z->start;
  154.     zs.zug.ziel  = z->ziel;
  155.     LoescheBaum( &k );
  156.     Zeit( &(zs.zeit) );
  157.     zs.knoten = kn;
  158.     zs.wertung = GesamtWert( s, &(zs.zug) );
  159.     return( &zs );
  160. }
  161.  
  162. long
  163. ZugBaumI( s, ks, k, fa, iteration, sp )
  164.     Figur s[ 9 ][ 9 ];
  165.     struct Knoten **ks, **k;
  166.     Farbe fa;
  167.     int iteration;
  168.     Special sp;
  169. {
  170.     int i, j;
  171.     long knoten;
  172.     Feld *fe;
  173.     Feld fes;
  174.     struct Knoten **kmerk;
  175.     struct Knoten *k1;
  176.  
  177.     knoten = 0;
  178.     kmerk = k;
  179.  
  180.      /* Spielbrett nach eigenen Figuren durchsuchen: */
  181.     for( i=1; i<=8; i++ )
  182.         for( j=1; j<=8; j++ )
  183.             if( (s[ i ][ j ] & farbmask) == fa ) {
  184.  
  185.                  /* mögliche Züge der Figur ermitteln: */
  186.                 fes = i << 4 | j;
  187.                 switch( s[ i ][ j ] & figmask ) {
  188.                 case bauer:     fe = Bauer( s, fes, sp );   break;
  189.                 case springer:  fe = Springer( s, fes );    break;
  190.                 default:        fe = RestFig( s, fes, sp ); break;
  191.                 }
  192.  
  193.                  /* alle neuen Züge in den Zugbaum: */
  194.                 while( *fe ) {
  195.                     if(( k1 = GibKnoten()) == 0L ) {
  196.                         LoescheBaum( ks );
  197.                         SchliesseDisplay();
  198.                         exit( 1 );
  199.                     }
  200.                     knoten ++;
  201.                     k1->zug.figur = s[ i ][ j ];
  202.                     k1->zug.start = fes;
  203.                     k1->zug.ziel  = *fe;
  204.                     k1->nachbar = k1->nachfolger = 0L;
  205.                     *kmerk = k1;
  206.                     kmerk = &(k1->nachbar);
  207.                     fe ++;
  208.                 }
  209.             }
  210.  
  211.     if( knoten )
  212.          /* alle neuen Züge bewerten: */
  213.         knoten += ZugBaumII( s, ks, k, fa, iteration, sp );
  214.  
  215.     return( knoten );
  216. }
  217.  
  218. long
  219. ZugBaumII( s, ks, k, fa, iteration, sp )
  220.     Figur s[ 9 ][ 9 ];
  221.     struct Knoten **ks, **k;
  222.     Farbe fa;
  223.     int iteration;
  224.     Special sp;
  225. {
  226.     long knoten, kneu;
  227.     int bonus, figwert, best;
  228.     struct Knoten *k1, *k2;
  229.     int sx, sy, zx, zy;
  230.     Figur fi;
  231.     int spz, spbonus;
  232.     Special sps;
  233.  
  234.     knoten = 0;
  235.     k1 = *k;
  236.  
  237.     while( k1 ) {
  238.  
  239.     sx = k1->zug.start >> 4;       sy = k1->zug.start & yposmask;
  240.         zx = k1->zug.ziel >> 4;        zy = k1->zug.ziel & yposmask;
  241.  
  242.          /* bei Bauernumwandlung gibt's Bonuspunkte: */
  243.         if( (k1->zug.figur & figmask) == bauer && (zy == 1 || zy == 8) )
  244.             bonus = Figurwert[ dame ] - Figurwert[ bauer ];
  245.         else
  246.             bonus = 0;
  247.  
  248.          /* Figuren schlagen bringt auch Punkte: */
  249.         fi = s[ zx ][ zy ];
  250.         figwert = ( fi == leer ) ? 0 : Figurwert[ fi & figmask ] +
  251.           Stellungswert( fi, k1->zug.ziel );
  252.  
  253.      /* jeweils Punkte für Rochade und ep-Schlagen: */
  254.     if( (k1->zug.figur&figmask)==koenig && (zx-sx==2 || sx-zx==2) )
  255.         spbonus = 100;
  256.     else if( (k1->zug.figur&figmask)==bauer && fi==leer && sx!=zx )
  257.         spbonus = 100;
  258.     else
  259.         spbonus = 0;
  260.  
  261.          /* auch Gegenzüge erkunden? */
  262.         if( iteration > 1 ) {
  263.  
  264.          /* neue Special - Variable: */
  265.         sps = sp & ~epmask;
  266.         if( (k1->zug.figur&figmask)==bauer && (zy-sy==2 || sy-zy==2) )
  267.         sps |= sx;
  268.         if( (k1->zug.figur&figmask)==koenig )
  269.         if( (k1->zug.figur&farbmask)==weiss )
  270.             sps &= ~wroch;
  271.         else
  272.             sps &= ~sroch;
  273.         if( (k1->zug.figur&figmask)==turm )
  274.         if( (k1->zug.figur&farbmask)==weiss ) {
  275.             if( sx==1 )
  276.             sps &= ~wlroch;
  277.             else if( sx==8 )
  278.             sps &= ~wkroch;
  279.         } else
  280.             if( sx==1 )
  281.             sps &= ~slroch;
  282.             else
  283.             sps &= ~skroch;
  284.  
  285.              /* Zug auf Spielbrett ausführen: */
  286.         s[sx][sy] = leer; spz = 0;
  287.         if( (k1->zug.figur&figmask)==koenig && (zx-sx==2 || sx-zx==2) ) {
  288.         spz = 1; s[zx][zy] = k1->zug.figur;
  289.         if( zx==7 ) {
  290.             s[6][sy] = s[8][sy]; s[8][sy] = leer;
  291.         } else {
  292.             s[4][sy] = s[1][sy]; s[1][sy] = leer;
  293.         }
  294.         } else if( (k1->zug.figur&figmask)==bauer && fi==leer && sx!=zx ) {
  295.         spz = 1; s[zx][zy] = k1->zug.figur; s[zx][sy] = leer;
  296.         } else if( bonus ) {
  297.         s[zx][zy] = fa|dame;
  298.         } else
  299.         s[zx][zy] = k1->zug.figur;
  300.  
  301.              /* Unterbaum aufbauen lassen: */
  302.             kneu = ZugBaumI( s, ks, &(k1->nachfolger),
  303.               fa == weiss ? schwarz : weiss, iteration-1, sps );
  304.             knoten += kneu;
  305.  
  306.              /* besten Gegenzug ermitteln: */
  307.             if( kneu ) {
  308.                 best = -30000;
  309.                 k2 = k1->nachfolger;
  310.                 do {
  311.                     if( k2->zugwertung > best )
  312.                         best = k2->zugwertung;
  313.                     k2 = k2->nachbar;
  314.                 } while( k2 );
  315.             } else
  316.                 best = 5000;
  317.  
  318.              /* Unterbaum wegwerfen: */
  319.             LoescheBaum( &(k1->nachfolger) );
  320.  
  321.              /* Zug auf Spielbrett rückgängig machen: */
  322.         s[sx][sy] = k1->zug.figur; s[zx][zy] = fi;
  323.         if( spz )
  324.         if( zx-sx==2 || sx-zx==2 ) {
  325.             if(zx==7) {
  326.             s[8][sy] = s[6][sy]; s[6][sy] = leer;
  327.             } else {
  328.             s[1][sy] = s[4][sy]; s[4][sy] = leer;
  329.             }
  330.         } else
  331.             s[zx][sy] = bauer|(zy==6?schwarz:weiss);
  332.  
  333.         } else
  334.             best = 0;
  335.  
  336.          /* auch Positionswechsel kann Punkte bedeuten: */
  337.         k1->zugwertung = bonus + spbonus + figwert - best +
  338.           Stellungswert( k1->zug.figur, k1->zug.ziel ) -
  339.           Stellungswert( k1->zug.figur, k1->zug.start );
  340.  
  341.         k1 = k1->nachbar;
  342.     }
  343.  
  344.     return( knoten );
  345. }
  346.  
  347. LoescheBaum( k )
  348.     struct Knoten **k;
  349. {
  350.     struct Knoten *k1, *kmerk;
  351.  
  352.     k1 = *k;
  353.     *k = 0L;
  354.     while( k1 ) {
  355.         LoescheBaum( &(k1->nachfolger) );
  356.         kmerk = k1->nachbar;
  357.         NimmKnoten( k1 );
  358.         k1 = kmerk;
  359.     }
  360. }
  361.  
  362. Stellungswert( fi, fe )
  363.     Figur fi;
  364.     Feld fe;
  365. {
  366.     int fstdim;
  367.  
  368.     fstdim = ( fi == wbauer ) ? 0 : ( fi & figmask );
  369.     return( Stelwert[ fstdim ][ 8 - (fe & yposmask) ][ (fe >> 4)-1 ] );
  370. }
  371.  
  372. GesamtWert( s, z )
  373.     Figur s[ 9 ][ 9 ];
  374.     struct Zug *z;
  375. {
  376.     int sx, sy, zx, zy;
  377.     Figur fi;
  378.     int spz;
  379.     long wert;
  380.     int i, j, neu;
  381.     Feld fe;
  382.  
  383.     sx = z->start >> 4; sy = z->start & yposmask;
  384.     zx = z->ziel >> 4;  zy = z->ziel & yposmask;
  385.      /* Zug ausführen: */
  386.     fi = s[zx][zy]; s[sx][sy] = leer; spz = 0;
  387.     if( (z->figur&figmask)==koenig && (zx-sx==2 || sx-zx==2) ) {
  388.     spz = 1; s[zx][zy] = z->figur;
  389.     if( zx==7 ) {
  390.         s[6][sy] = s[8][sy]; s[8][sy] = leer;
  391.     } else {
  392.         s[4][sy] = s[1][sy]; s[1][sy] = leer;
  393.     }
  394.     } else if( (z->figur&figmask)==bauer && fi==leer && sx!=zx ) {
  395.     spz = 1; s[zx][zy] = z->figur; s[zx][sy] = leer;
  396.     } else if( (z->figur&figmask)==bauer && (zy==1 || zy==8) ) {
  397.     s[zx][zy] = (z->figur&farbmask)|dame;
  398.     } else
  399.     s[zx][zy] = z->figur;
  400.  
  401.     wert = 0;
  402.     for( i=1; i<=8; i++ )
  403.         for( j=1; j<=8; j++ )
  404.             if( s[ i ][ j ] != leer ) {
  405.                 fe = i << 4 | j;
  406.                 neu = Figurwert[ s[ i ][ j ] & figmask ] +
  407.                   Stellungswert( s[ i ][ j ], fe );
  408.                 if( (s[ i ][ j ] & farbmask) == weiss )
  409.                     wert += neu;
  410.                 else
  411.                     wert -= neu;
  412.             }
  413.  
  414.      /* Zug rückgängig machen: */
  415.     s[sx][sy] = z->figur; s[zx][zy] = fi;
  416.     if( spz )
  417.     if( zx-sx==2 || sx-zx==2 ) {
  418.         if( zx==7 ) {
  419.         s[8][sy] = s[6][sy]; s[6][sy] = leer;
  420.         } else {
  421.         s[1][sy] = s[4][sy]; s[4][sy] = leer;
  422.         }
  423.     } else
  424.         s[zx][sy] = bauer|(zy==6?schwarz:weiss);
  425.  
  426.     return( (int)wert );
  427. }
  428.